package Network;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream.GetField;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import javax.swing.JOptionPane;

import org.w3c.dom.Document;
import org.zoolu.tools.Log;




import DTO.AccountDTO;
import PhanQuyen.Quyen;


import GiaoDien.frmBieuQuyetMoiRaKhoiNhom;
import GiaoDien.frm_ThaoLuanNhom;

import XML.CMember;
import XML.ReadWriteFile;
import XML.ReadXML;
import XML.WriteXML;
import it.unipr.ce.dsg.s2p.message.Payload;
import it.unipr.ce.dsg.s2p.org.json.JSONException;
import it.unipr.ce.dsg.s2p.org.json.JSONObject;
import it.unipr.ce.dsg.s2p.peer.Peer;
import it.unipr.ce.dsg.s2p.peer.PeerDescriptor;
import it.unipr.ce.dsg.s2p.sip.Address;
import it.unipr.ce.dsg.s2p.util.FileHandler;

public class Class_GV_Send_Receive extends Peer {
	public AccountDTO account = null;
	final private String SEPARATOR = "/";
	final private String SEPARATOR1 = "##";
	FileHandler fileHandler;
	Log log;
	public int iIDDetailLearning = 2;
	public int iIDLearner = 8;
	public String sIPReceive = "255.255.255.255:255";
	public String sIP = "";
	public ReadXML rXML = new ReadXML();
	public WriteXML wXML = new WriteXML();
	public String sXML = "ip.xml";
	public frm_ThaoLuanNhom frmChinh;
	public boolean flagSendQuestion = false;
	ArrayList<Object> arr = new ArrayList<Object>();
	// public Dongho timer_Feedback;
	// public DongHoFeel timer_FeedbackFeel;
	// public DongHoGroup timer_Group;
	int idpart = 0;
	boolean blloaibaitap = true;
	public boolean blgroup = false;
	public ArrayList<ArrayList<Object>> arrDSNhom = new ArrayList<ArrayList<Object>>();
	String sTenBaiTap = "";
	int idex = 0;
	int idmax = 0;

	public Class_GV_Send_Receive(String pathConfig, String key, String name, int port, frm_ThaoLuanNhom frmChinh) {
		super(pathConfig, key, name, port);
		this.frmChinh = frmChinh;
		peerDescriptor.setContactAddress(sipProvider.AUTO_CONFIGURATION);
		try {

		} catch (Exception ex) {
		}
		init();
		//
	}
//===============================
	public AccountDTO getAccount() {
		return this.account;
	}

	public PeerDescriptor getPeerDescriptor() {
		return this.peerDescriptor;
	}
	public String getPeerDescriptorName() {
		return peerDescriptor.getName();
	}

	public void MyLog(String s) {

		System.out.println(s);
	}
	public String getAddressPeer() {

		return getAddress().getURL();
	}

	public String getContactAddressPeer() {

		return peerDescriptor.getContactAddress();
	}
	public String getSimpleIP(){
		return getAddress().getHost().toString();
	}
	private boolean nhomDaFull() {
		return true;
	}
	//======================

	/*
	 * send a message is fail, this func will be called.
	 */
	@Override
	protected void onDeliveryMsgFailure(String peerMsg, Address receiver, String contentType) {
		//
	}

	/*
	 * when a message is send success, need to process some work
	 */
	@Override
	protected void onDeliveryMsgSuccess(String peerMsg, Address receiver, String contentType) {
		//
		System.out.println("Đã gởi thành công cho " + receiver + "##" + peerMsg);

		// this.halt();
	}

	// this func will be receive a message
	@Override
	protected void onReceivedJSONMsg(JSONObject peerMsg, Address sender) {
		System.out.println("Đã nhận từ: " + sender + ":: " + peerMsg.toString());

		JSONObject params = null;
		try {

			params = peerMsg.getJSONObject("payload").getJSONObject("params");
		} catch (JSONException e1) {
			e1.printStackTrace();
		}
		try {
			String sIPSend = sender.getURL();
			String[] temp1 = sIPSend.split("@");
			sIPReceive = temp1[1];
			String type = (String) peerMsg.get("type");
			// cam noi
			if (type.equals(Protocol.STOP_TALKING_ONE_MEMBER)) {
				NhanYeuCauNgungThaoLuan(params, sender);

			}
			// cho noi
			else if (type.equals(Protocol.ACCEPT_TALKING_ONE_MEMBER)) {
				NhanChoPhepThaoLuan();
			}// chat
			else if (type.equals(Protocol.CHAT_PEER_MESSAGE)) {
				// truyen thong diep qua ham chat
				MyLog("da nhan thong diep chat");
				ReceiveMessageChatPeer(params, sender);

				// NhanTinNhanTroChuyenRieng(params, sender);
				NhanTinNhanThaoLuan(params, sender);
			}// ko co quyen nhan tin nhan chat
			else if (type.equals(Protocol.CHAT_FEEDBACK_NON_RULE)) {
				// CloseChatPeerActivity();
				NhanPhanHoiKhongCoQuyenTroChuyenRieng(params, sender);
			}// nhan tin nhan yeu cau bieu quyet moi nguoi khac ra khoi nhom
			else if (type.equals(Protocol.KICK_MEMBER_OUT_MESSAGE)) {
				ReceiveVoteKickMember(params, sender);

			}// nhan duoc phan hoi moi nguoi khac ra khoi nhom
			else if (type.equals(Protocol.KICK_MEMBER_OUT_FEEDBACK)) {
				MyLog("vao fan hoi vote");
				// ShowMessageNotice("da nhan dc tin nhan phan hoi Kick");
				ReceiveFeedbackKickMember(params);
			}// nhan dc ket qua cuoi dung
			else if (type.equals(Protocol.KICK_MEMBER_OUT_RESULT)) {
				// ShowMessageNotice("da nhan dc ket qua Kick");
				ReceiveResultKickMember(params);

			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	// cac ham Send message cua he thong
	// chat rieng
	public void ReceiveMessageChatPeer(JSONObject params, Address sender) throws NumberFormatException,
	JSONException{
		MyLog( "vao ReceiveMessageChatPeer");
		if (getAccount().getRuleById(7) != null && getAccount().getRuleById(7).getReceive()) {
			Iterator<String> iter = params.keys();
			while (iter.hasNext()) {
				MyLog( "vao while ReceiveMessageChatPeer");
				String key = iter.next();
				String s = null;
				try {
					s = params.get(key).toString();
					// username/text/ip
					MyLog( "s=" + s);

				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				MyLog( "Key " + key);
				if (key.equals("Message")) {
					MyLog( "key la " + key);
					String[] sTemp = s.split("/");
					final String acc = sTemp[0];
					final String ipsend = sTemp[2];
					String mess = sTemp[1];// getMessage(sTemp);
					MyLog( "controller username: " + acc);
					MyLog( "controller ip send: " + ipsend);
					MyLog( "Sender ip=" + sender.getURL());
					MyLog( "controller mess: " + mess);
					// ---------tien hanh ghi file----------

					// ReadWriteFileController.writeTXT("Peer_"+acc+"_Content.txt",
					// fullName + ":" + mess);
//					ReadWriteFileController.writeTXTPath(ReadWriteFileController.DIRECTORYCHATPEER + "Peer_" + acc
//							+ "_Content.txt", acc + ":" + mess);
					MyLog( "da ghi file xong");

					String userNameChatting = "moi them";//frmChatPeerActivity._FriendChatting;
					MyLog( "=====================username dang chat=" + userNameChatting);

					if (userNameChatting == null) {
						//frmChatPeerActivity._FriendChatting = acc;
						//ShowChatPeer(ipsend, acc);
					} else {
						MyLog( "----------Acc = " + acc);
						MyLog( "----------chatting = " + userNameChatting);
						if (userNameChatting.equals(acc)) {// la dang chat voi
															// minh
							MyLog( "dang chat together");
						//	handler.post(_runUpdateMsg);
							// init_runnableUpdateMsg();
							// handler.post(frmChatPeerActivity._runUpdateMsg);
							MyLog( "run update message xong");
						} else {// minh dang chat voi nguoi khac
							MyLog( "dang chat voi nguoi khac");
							// show notification co sender gui tin nhan
//							NotificationController.sendNotification(ActivityController.getPeerActivity()
//									.getBaseContext(), frmChatPeerActivity.class, "Nhận tin nhắn của " + acc, mess,
//									Notification.DEFAULT_SOUND, acc, ipsend);
						}
					}
					

					MyLog( "networkcontroller vao conversation nhan tin nhan");
					// ActivityController.hander.post(new Runnable() {
					//
					// @Override
					// public void run() {
					// // TODO Auto-generated method stub
					// frmConversation.receiveMessage(message);
					// }
					// });

					// frmMyConversation.mess=message;
					// handler.post(frmMyConversation.raReceiveMessage);

					MyLog( "conversation nhan tin nhan xong");
				}
			}
		} else {
			MyLog( "gui phan hoi ko chat net layer");
			// ShowMessageNotice("Bạn không có quyền nhận tin nhắn trò chuyện.");
			 GuiPhanHoiKhongCoQuyenChat(sender,getAccount().get_Username());
		}
	}

	// end chat rieng
	public void NhanTinNhanThaoLuan(JSONObject params, Address address) throws NumberFormatException,
			JSONException {
		String key;
		Quyen quyen =  getAccount().getRuleById(4);
		if (quyen != null && quyen.getReceive()) {
			Iterator<String> listKey = params.keys();
			while (listKey.hasNext()) {
				key = listKey.next();
				String s = null;
				try {
					s = params.get(key).toString();
				} catch (JSONException e) {
					MyLog( "Lỗi trong hàm NhanTinNhanThaoLuan: " + address.toString());
					e.printStackTrace();
				}
				if (key.equals("Content_Chat")) {
					// ShowMessageChat(s, address.getURL());
					MyLog( "NhanTinNhanThaoLuan từ: " + address.toString());
				}
			}
		} else {
			MyLog( "Không có quyền NhanTinNhanThaoLuan");
			MyLog( quyen.toString());
			//  ShowMessageNotice("Bạn không có quyền nhận tin nhắn trò chuyện.");
			//  GuiPhanHoiKhongCoQuyenChat(address);
		}
	}

	public void GuiYeuCauNgungThaoLuan(final Address toAdd, int time) {
		MyLog("vao Controller ngung noi");

		MyLog("vao if ngung noi");
		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.STOP_TALKING_ONE_MEMBER);
		Payload pl = new Payload();
		pl.addParam("TimeStopTalk", time);
		message.setPayload(pl);
		// String message="Ban da bi ngung noi";
		send(new Address(toAdd), message);

		MyLog("gui yeu cau ngung noi");
	}

	public void GuiChoPhepThaoLuan(Address toAddress) {
		MyLog("vao Controller cho phep noi");
		 boolean YourRule = getAccount().getRuleById(6).getSend();
		 if (YourRule) {
		MyLog("vao if cho noi");
		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.ACCEPT_TALKING_ONE_MEMBER);
		send(new Address(toAddress), message);
		MyLog("gui yeu cau cho noi");
		 } else {
		 MyLog( "ko get dc quyen");
		 // ShowMessageNotice(Protocol.NON_RULE_MESSAGE);
		 }
	}

	public void NhanYeuCauNgungThaoLuan(JSONObject params, Address address) throws NumberFormatException, JSONException {
		// quyen thao luan =false==4 //tam thoi la quyen chat rieng=7
		 if ( getAccount().getRuleById(7) != null) {
		 getAccount().getRuleById(7).setSend(false);
		Iterator<String> listKey = params.keys();
		String key;
		int time = 0;
		while (listKey.hasNext()) {
			MyLog("vao while");
			key = listKey.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (key.equals("TimeStopTalk")) {
				time = Integer.parseInt(s);
			}

		}
		// MyLog( "moi sua: Send " + getAccount().getRuleById(7).getSend());
		String s = Protocol.STOP_TALKING_MESSAGE + " trong vòng " + time + " giây. Vui lòng chờ.";
		// // ShowMessageNotice(s);
		 }
	}

	public void NhanChoPhepThaoLuan() {
		 if ( getAccount().getRuleById(7) != null) {
		 getAccount().getRuleById(7).setSend(true);
		 MyLog( "Da sua lai wuyen noi" +
		 getAccount().getRuleById(7).getSend());
		 //// ShowMessageNotice(Protocol.ACCEPT_TALKING_MESSAGE);
		 }
	}

	// Quyen 7
	public void GuiTinNhanChat(Address toAddress, String content) {

		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.CHAT_MESSAGE);
		Payload pl = new Payload();
		pl.addParam("Content_Chat", content);
		message.setPayload(pl);
		send(new Address(toAddress), message);
		MyLog("GuiTinNhanChat to" + toAddress.toString());
	}

	public void GuiPhanHoiKhongCoQuyenChat(Address toAddress, String username) {
		MyLog("gui phan hoi ko co quyen chat");
		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.CHAT_FEEDBACK_NON_RULE);
		Payload pl = new Payload();
		pl.addParam("Content", username + " không có quyền nhận tin nhắn trò chuyện.");
		message.setPayload(pl);
		send(new Address(toAddress), message);
	}

	public void NhanPhanHoiKhongCoQuyenTroChuyenRieng(JSONObject params, Address address) throws NumberFormatException,
			JSONException {
		String key;

		Iterator<String> listKey = params.keys();
		while (listKey.hasNext()) {
			key = listKey.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (key.equals("Content")) {

				// ShowMessageNotice(s);
			}
		}

	}

	public void ReceiveVoteKickMember(JSONObject params, Address address) throws NumberFormatException,
			JSONException {
		MyLog( "Vao ReceiveVoteKickMember");

		MyLog( "co quyen bieu quyet");
	//	frmBieuQuyetMoiRoiNhom.senderKick = address;
		//  ShowMessageNotice("da nhan dc tin nhan Kick");
		// ActivityController.ShowMessage("nhan dc");
		String key;
		int time = 0;
		String ipBeingKick = "";
		String ip =  getAddressPeer();
		MyLog( "my ip " + ip);
		Iterator<String> listKey = params.keys();
		String userNameBeingKick = "";
		while (listKey.hasNext()) {
			MyLog( "vao while");
			key = listKey.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (key.equals("Time")) {
				MyLog( "key = time");
				MyLog( "s =" + s);
				time = Integer.parseInt(s);
				MyLog( "time=" + time);
			}
			if (key.equals("IPBeingKick")) {
				MyLog( "key = being kick ip");
				ipBeingKick = s;
				MyLog( "being kick ip=" + ipBeingKick);
			}
			if (key.equals("UserNameBeing")) {
				userNameBeingKick = s;
			}
		}
		MyLog( "ra khoi while");

		//  SetTimeKick(time);

		// có viết hàm thông qua các class controller va activitycontroller
		// nhung ko thanh cong nen gan truc tiep
		MyLog( "settime kick");
		MyLog( "time to vote = " + time);
		Quyen myRule =  getAccount().getRuleById(13);
		if (myRule != null && myRule.getSend()) {
			if (ip.equals(ipBeingKick) == false) {
				MyLog( "ko khop ip trong send vote");
			frmBieuQuyetMoiRaKhoiNhom frm=new frmBieuQuyetMoiRaKhoiNhom(frmChinh, "", "", "", "", time);
			frm.setVisible(true);
				return;
			}
		}
		MyLog( "la nguoi bi kick");
		//  ShowMessageNotice("Các thành viên trong nhóm đang biểu quyết để mời bạn rời khỏi nhóm.");
		// ShowMessageNoticeTAB("Các thành viên trong nhóm đang biểu quyết để mời bạn rời khỏi nhóm.");
		// set tat ca cac quyen cua nguoi nay la false.
		// ko cho chat rieng
		  getAccount().getRuleById(7).setSend(false);
		// ko cho thao luan
		  getAccount().getRuleById(4).setSend(false);
		// ko cho bieu quyet
		  getAccount().getRuleById(8).setSend(false);
		// ko cho Chia sẻ tài liệu (Up tài liệu)
		  getAccount().getRuleById(9).setSend(false);
		// ko cho Tải tài liệu
		  getAccount().getRuleById(10).setSend(false);
		// ko cho xóa tài liệu
		  getAccount().getRuleById(11).setSend(false);
		// ko cho Biểu quyết
		  getAccount().getRuleById(13).setSend(false);
		// ko cho Đánh giá bản thân và người khác
		  getAccount().getRuleById(15).setSend(false);

		// phai phong truong hop no nhan duoc thong bao nay tu nhien roi
		// khoi nhom.ko cho quyet dinh.
		MyLog( "Da show thong bao ");
	}

	public void ReceiveFeedbackKickMember(JSONObject params) throws NumberFormatException, JSONException {
		String key;
		Iterator<String> listKey = params.keys();
		while (listKey.hasNext()) {
			key = listKey.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (key.equals("VOTE")) {
				MyLog( "lay vote");
				if (s.equals("1")) {
				//	tabActivity.yesVote.add(1);
				} else if (s.equals("0")) {
			//		tabActivity.noVote.add(1);
				}
			}
		}
	}

	public void ReceiveResultKickMember(JSONObject params) throws NumberFormatException, JSONException {
		String key;
		int kq = -1;

		Iterator<String> listKey = params.keys();
		String myIP =  getAddressPeer();
		MyLog( "my IP=" + myIP);
		String ipBeingKick = "";
		while (listKey.hasNext()) {
			key = listKey.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (key.equals("Result")) {
				MyLog( "lay ket qua cuoi cung");
				if (s.equals("1")) {
					//  ShowMessageNotice("Thành viên trên đã bị mời khỏi nhóm");
					kq = 1;
				} else if (s.equals("0")) {
					kq = 0;
					//  ShowMessageNotice("Mời thành viên khỏi nhóm đã thất bại.");
				}
				MyLog( "ket qua cuoi cung = " + s);
			}
			if (key.equals("BeingKick")) {
				MyLog( "lay ip bi kick result");
				MyLog( "ip bi kick result : " + s);
				ipBeingKick = s;
				// MyLog("My ip result : "+myIP.getURL());
			}
		}
		//ArrayList<CMember> memberList = ReadXML.ReadMember(ReadWriteFileController.MEMBER_PATH);
		String ipPort = "sip:" + ipBeingKick;
	//	CMember ipMember = new CMember();
//		for (CMember m : memberList) {
//			if (m.get_ip().equals(ipPort)) {
//				ipMember = m;
//				break;
//			}

		//}
		if (ipBeingKick.equals(myIP)) {
			MyLog( "khop ip bi kick result");
			if (kq == 1) {
				MyLog( "kq bi kick result =1 ");
			//	 ShowMessageKicked();
				// xoa nguoi nay khoi danh sach nhom

			} else {
				MyLog( "kq bi kick result =0 ");
				//  ShowMessageNotice("Mời bạn rời khỏi nhóm đã thất bại.");
			//	 ShowMessageNoticeTAB("Mời bạn rời khỏi nhóm đã thất bại.");
			}
		} else {
			MyLog( "ko khop ip bi kick result");
			if (kq == 1) {
				MyLog( "kq bi kick result =1 ");
				String s = "";
				//s += ipMember.get_userName() + " đã bị mời ra khỏi nhóm.";
				//  ShowMessageNotice(s);
			//	 ShowMessageNoticeTAB(s);
			} else {
				MyLog( "kq bi kick result =0 ");
				//  ShowMessageNotice("Mời thành viên khỏi nhóm đã thất bại.");
			//	 ShowMessageNoticeTAB("Mời thành viên khỏi nhóm đã thất bại.");
			}

		}
	}

	// gửi thông báo cần biểu quyết để mời 1 thành viên ra khỏi nhóm
	public void SendVoteKickMember(Address beingKick, int time) {
		MyLog( "vao send vote");
		MyLog( "being ip = " + beingKick.toString());
		ArrayList<CMember> memberList = ReadXML.ReadMember("memberList.xml");
		MyLog( "size = " + memberList.size());
		String ipPort = "sip:" + beingKick.getURL();
		MyLog( "ip being gan= " + ipPort);
		CMember ipMember = new CMember();
		for (CMember m : memberList) {
			PeerListMessage message = new PeerListMessage(this.peerList);
			message.setType(Protocol.KICK_MEMBER_OUT_MESSAGE);
			Payload pl = new Payload();

			pl.addParam("Time", time);
			pl.addParam("IPBeingKick", beingKick.getURL());
	//		pl.addParam("UserNameBeing", ipMember.get_userName());

			MyLog( "ip bi kick " + beingKick.getURL());
			message.setPayload(pl);
			send(new Address(m.get_ip()), message);

		}
		
	}

	// gửi ý kiến biểu quyết về việc mời 1 thành viên ra khỏi nhóm
	public void SendFedbackKickMember(Address toAddress, int vote) {
		MyLog( "vao ham bieu quyet kick");
		// int vote=frmBieuQuyetMoiRoiNhom.YKienBieuQuyet;
		MyLog( "bieu quyet kick = " + vote);
		// Quyen myRule = getAccount().getRuleById(13);
		// if (myRule != null && myRule.getSend()) {
		MyLog( "vao if bieu quyet kick");
		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.KICK_MEMBER_OUT_FEEDBACK);
		Payload pl = new Payload();
		if (vote == 1) {
			MyLog( " bieu quyet kick = yes");
			pl.addParam("VOTE", "1");
		} else if (vote == 0) {
			MyLog( " bieu quyet kick = no");
			pl.addParam("VOTE", "0");
		} else {
			MyLog( " bieu quyet kick = khac");
		}
		message.setPayload(pl);
		send(toAddress, message);
		// } else {

		// NetworkController.ShowMessageNotice("bạn không có quyền biểu quyết kick");
		// MyLog( "ko co quyen bieu quyet kick");
		// }
	}

	// hàm gửi kết quả cuoi cung ve moi nguoi khac ra khoi nhom
	public void SendResultVoteKickMember(Address toAdd, int result, Address beingKickAdd) {
		MyLog( "vao ham SendResultVoteKickMember");

		MyLog( "vao if send result kick");
		PeerListMessage message = new PeerListMessage(this.peerList);
		message.setType(Protocol.KICK_MEMBER_OUT_RESULT);
		Payload pl = new Payload();

		pl.addParam("Result", result);
		pl.addParam("BeingKick", beingKickAdd.getURL());
		message.setPayload(pl);
		send(toAdd, message);
		MyLog( "da send result kick");

	}
	// end cac ham Send message cua he thong

	private void init() {
		if (nodeConfig.log_path != null) {
			// handler for write and read file
			fileHandler = new FileHandler();
			if (!fileHandler.isDirectoryExists(nodeConfig.log_path))
				fileHandler.createDirectory(nodeConfig.log_path);
			log = new Log(nodeConfig.log_path + "info_" + peerDescriptor.getAddress() + ".log", Log.LEVEL_MEDIUM);
		}
	}
}
